﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using CookComputing.XmlRpc;
using LevenBlog.Core.Entities;
using LevenBlog.Core.Data;
using LevenBlog.Core.Service;
using LevenBlog.Core.User;
using LevenBlog.Core.Cache;
using LevenBlog.Core.Mvc;
using LevenBlog.Core.Utils;

namespace LevenBlog.Core.WebService.MetaBlog
{
    public class MetaBlogApiOffice2k7 : XmlRpcService, CookComputing.MetaWeblog.IMetaWeblogOffice2k7, CookComputing.Blogger.IBlogger
    {
        public MetaBlogApiOffice2k7()
        {
        }

        protected IDbProvider CreateProvider()
        {
            IDbProvider provider = ProviderManager.Factory.CreateDbProvider();
            provider.Open();
            return provider;
        }

        private int ConvertBlogID(string id)
        {
            int blogid;
            int.TryParse(id, out blogid);
            return blogid;
        }

        private UrlHelper url;

        protected UrlHelper Url
        {
            get
            {
                if (url == null)
                {
                    url = new UrlHelper(new RequestContext(new HttpContextWrapper(Context), new RouteData()));
                }
                return url;
            }
        }

        protected string ReplacePath(IDbProvider provider, string text)
        {
            string filePath = Url.Action("file", "blog");
            //filePath = filePath.Substring(0, filePath.LastIndexOf('/'));
            string urlroot = Config.Get(provider).url;
            if (String.IsNullOrEmpty(urlroot))
                urlroot = String.Empty;
            if (urlroot.EndsWith("/"))
                urlroot = urlroot.Substring(0, urlroot.Length - 1);
            StringBuilder sb = new StringBuilder(text);
            sb.Replace("src=\"/skins", String.Format("src=\"{0}/skins", urlroot));
            sb.Replace(filePath, urlroot + filePath);
            return sb.ToString();
        }

        protected string RemovePath(IDbProvider provider, string text)
        {
            string filePath = Url.Action("file", "blog");
            string urlroot = Config.Get(provider).url;
            if (String.IsNullOrEmpty(urlroot))
                urlroot = String.Empty;
            if (!urlroot.EndsWith("/"))
                urlroot += "/";
            StringBuilder sb = new StringBuilder(text);
            sb.Replace(String.Format("src=\"{0}skins", urlroot), "src=\"/skins");
            sb.Replace(urlroot + filePath, filePath);
            return sb.ToString();
        }

        #region metaweblog

        public CookComputing.MetaWeblog.Post getPost(string postid, string username, string password)
        {
            using (IDbProvider provider = CreateProvider())
            {
                lb_user user = BlogUser.Get(provider, username);
                if (user != null && user.password == password.ToMD5())
                {
                    int blogid = ConvertBlogID(postid);
                    lb_blog blog = Blog.Get(provider, blogid);
                    if (blog != null)
                    {
                        CookComputing.MetaWeblog.Post post = new CookComputing.MetaWeblog.Post()
                        {
                            categories = new string[] { blog.Category.name },
                            dateCreated = blog.posttime,
                            description = ReplacePath(provider, blog.content),
                            enclosure = new CookComputing.MetaWeblog.Enclosure(),
                            link = Url.Action("view", "blog", new { id = blog.id.ToString() }),
                            permalink = Url.Action("view", "blog", new { id = blog.id.ToString() }),
                            postid = blog.id.ToString(),
                            title = blog.title,
                            userid = blog.postuser,
                            source = new CookComputing.MetaWeblog.Source()
                        };
                        return post;
                    }
                }
                return new CookComputing.MetaWeblog.Post();
            }
        }

        public object editPost(string postid, string username, string password, CookComputing.MetaWeblog.Post post, bool publish)
        {
            using (IDbProvider provider = CreateProvider())
            {
                lb_user user = BlogUser.Get(provider, username);
                if (user != null && user.password == password.ToMD5())
                {
                    Authority authority = new Authority();
                    authority.Fill(user.usertype.competence);
                    if (authority.Edit)
                    {
                        int blogid = ConvertBlogID(postid);
                        lb_blog blog = Blog.Get(provider, blogid);
                        if (blog != null)
                        {
                            if (post.categories != null)
                            {
                                lb_category selectcategory = Category.Get(provider).FirstOrDefault(c => c.name == post.categories[0]);
                                if (selectcategory != null)
                                    blog.categoryid = selectcategory.id;
                            }
                            blog.content = post.description;
                            blog.title = post.title;
                            Blog.Update(provider, blog);
                            return (object)true;
                        }
                    }
                }
                return (object)false;
            }
        }

        public CookComputing.MetaWeblog.CategoryInfo[] getCategories(string blogid, string username, string password)
        {
            using (IDbProvider provider = CreateProvider())
            {
                lb_user user = BlogUser.Get(provider, username);
                if (user != null && user.password == password.ToMD5())
                {
                    IList<lb_category> categories = Category.Get(provider);
                    IList<CookComputing.MetaWeblog.CategoryInfo> categoryinfos = new List<CookComputing.MetaWeblog.CategoryInfo>();
                    foreach (lb_category category in categories)
                    {
                        CookComputing.MetaWeblog.CategoryInfo info = new CookComputing.MetaWeblog.CategoryInfo()
                        {
                            title = category.name,
                            categoryid = category.id.ToString(),
                            description = category.name,
                            htmlUrl = Url.Action("list", "blog", new { category = category.id.ToString() }),
                            rssUrl = Url.Action("rss", "blog", new { category = category.id.ToString() })
                        };
                        categoryinfos.Add(info);
                    }
                    return categoryinfos.ToArray();
                }
                return null;
            }
        }

        public CookComputing.MetaWeblog.Post[] getRecentPosts(string postid, string username, string password, int numberOfPosts)
        {
            using (IDbProvider provider = CreateProvider())
            {
                lb_user user = BlogUser.Get(provider, username);
                if (user != null && user.password == password.ToMD5())
                {
                    IList<lb_blog> blogList = Blog.Get(provider, numberOfPosts, 1, BlogState.Show);
                    IList<CookComputing.MetaWeblog.Post> postList = new List<CookComputing.MetaWeblog.Post>();
                    foreach (lb_blog blog in blogList)
                    {
                        CookComputing.MetaWeblog.Post post = new CookComputing.MetaWeblog.Post()
                        {
                            categories = new string[] { blog.Category.name },
                            dateCreated = blog.posttime,
                            description = ReplacePath(provider, blog.content),
                            enclosure = new CookComputing.MetaWeblog.Enclosure(),
                            link = Url.Action("view", "blog", new { id = blog.id.ToString() }),
                            permalink = Url.Action("view", "blog", new { id = blog.id.ToString() }),
                            postid = blog.id.ToString(),
                            title = blog.title,
                            userid = blog.postuser,
                            source = new CookComputing.MetaWeblog.Source()
                        };
                        postList.Add(post);
                    }
                    return postList.ToArray();
                }
                return null;
            }
        }

        public string newPost(string postid, string username, string password, CookComputing.MetaWeblog.Post post, bool publish)
        {
            using (IDbProvider provider = CreateProvider())
            {
                lb_user user = BlogUser.Get(provider, username);
                if (user != null && user.password == password.ToMD5())
                {
                    Authority authority = new Authority();
                    authority.Fill(user.usertype.competence);
                    if (authority.Post && publish)
                    {
                        int blogid = ConvertBlogID(postid);
                        lb_blog blog = new lb_blog();
                        if (post.categories != null)
                        {
                            lb_category selectcategory = Category.Get(provider).FirstOrDefault(c => c.name == post.categories[0]);
                            if (selectcategory != null)
                                blog.categoryid = selectcategory.id;
                            else
                                throw new Exception("未找到该分类");
                        }
                        else
                        {
                            lb_category defaultcategory = Category.Get(provider).FirstOrDefault(c => c.isurl == false);
                            if (defaultcategory != null)
                                blog.categoryid = defaultcategory.id;
                            else
                                throw new Exception("请先添加分类.");
                        }
                        blog.posttime = DateTime.Now;
                        blog.intro = post.description;
                        blog.content = post.description;
                        blog.isshow = true;
                        blog.postuser = user.name;
                        blog.title = post.title;
                        blog.mails = user.id + "|";
                        blog.come = "本站原创";
                        blog.comeurl = Config.Get(provider).url;
                        blog.hits = 0;
                        Blog.Insert(provider, blog);
                        ObjectCache.RegexRemove(".*blog.*");
                        CalendarCache.Delete(blog.posttime.Year, blog.posttime.Month);
                        return Blog.Get(provider, 1, 1, BlogState.Show)[0].id.ToString();
                    }
                }
                return "0";
            }
        }

        public CookComputing.MetaWeblog.UrlData newMediaObject(int blogid, string username, string password, CookComputing.MetaWeblog.FileData file)
        {
            using (IDbProvider provider = CreateProvider())
            {
                lb_user user = BlogUser.Get(provider, username);
                if (user != null && user.password == password.ToMD5())
                {
                    Authority authority = new Authority();
                    authority.Fill(user.usertype.competence);
                    if (authority.Upload)
                    {
                        if (file.bits.Length > authority.UploadSize * 1024)
                            throw new Exception("上传文件大小超过限制.");
                        PostFile postFile = new PostFile(file.name, file.type, file.bits);
                        FileUpload fileUpload = new FileUpload();
                        fileUpload.MaxLength = authority.UploadSize * 1024;
                        fileUpload.UploadPath = Config.Get(provider).uploadpath;
                        fileUpload.Save(postFile);
                        lb_file blogFile = new lb_file()
                        {
                            hits = 0,
                            name = fileUpload.SaveName,
                            intro = fileUpload.PostName,
                            path = fileUpload.SavePath,
                            time = DateTime.Now,
                            type = fileUpload.Type
                        };
                        File.Insert(provider, blogFile);
                        lb_file savedFile = File.Get(provider, 1, 1)[0];
                        return new CookComputing.MetaWeblog.UrlData()
                        {
                            url = ReplacePath(provider, Url.Action("file", "blog", new { id = savedFile.id }))
                        };
                    }
                }
                return new CookComputing.MetaWeblog.UrlData()
                {
                    url = ReplacePath(provider, Config.Get(provider).logo)
                };
            }
        }

        #endregion

        #region blogger

        public bool deletePost(string appKey, string postid, string username, string password, bool publish)
        {
            using (IDbProvider provider = CreateProvider())
            {
                lb_user user = BlogUser.Get(provider, username);
                if (user != null && user.password == password.ToMD5())
                {
                    int blogid = ConvertBlogID(postid);
                    Blog.Delete(provider, blogid);
                    return true;
                }
                return false;
            }
        }

        public CookComputing.Blogger.BlogInfo[] getUsersBlogs(string appKey, string username, string password)
        {
            using (IDbProvider provider = CreateProvider())
            {
                lb_user user = BlogUser.Get(provider, username);
                if (user != null && user.password == password.ToMD5())
                {
                    //IList<lb_blog> blogList = Blog.GetFromUser(provider, username, 30, 1, BlogState.None);
                    //IList<CookComputing.Blogger.BlogInfo> postList = new List<CookComputing.Blogger.BlogInfo>();
                    //foreach (lb_blog blog in blogList)
                    //{
                    //    CookComputing.Blogger.BlogInfo post = new CookComputing.Blogger.BlogInfo()
                    //    {
                    //        blogid = blog.id.ToString(),
                    //        blogName = blog.title,
                    //        url = Url.Action("view", "blog", new { id = blog.id.ToString() })
                    //    };
                    //    postList.Add(post);
                    //}
                    //return postList.ToArray();
                    CookComputing.Blogger.BlogInfo info = new CookComputing.Blogger.BlogInfo()
                    {
                        blogid = Config.Get(provider).id.ToString(),
                        blogName = Config.Get(provider).title,
                        url = Config.Get(provider).url
                    };
                    return new CookComputing.Blogger.BlogInfo[] { info };
                }
                return null;
            }
        }

        #endregion
    }
}
